
#include <iostream>
#include "symboltable.hpp"

void printSymbol( const Symbol& symbol );

int main()
{
  // Creates a symbol table
  SymbolTable symbolTable;

  // Adds a new symbol to symbolTable, named 'hello' at level '0'.
  symbolTable.AddSymbol( "hello" );
  symbolTable.AddSymbol( "world" );
  symbolTable.AddSymbol( "foo" );
  symbolTable.AddSymbol( "bar" );
  symbolTable.AddSymbol( "test" );
  symbolTable.AddSymbol( "me" );
  symbolTable.AddSymbol( "plz" );

  symbolTable.EnterBlock();
  {
    symbolTable.AddSymbol( "test" );
    symbolTable.AddSymbol( "me" );
    symbolTable.AddSymbol( "plz" );

  symbolTable.GetSymbol( "plz" ).SetOffset( 48 );
  symbolTable.GetSymbol( "plz" ).SetType( "float" );
  }
  symbolTable.ExitBlock();

  // Gets a reference to the newly created symbol.
  Symbol& helloSymbol = symbolTable.GetSymbol( "hello" );

  // Sets an 'offset' and a 'type' to the symbol.
  helloSymbol.SetOffset( 16 );
  helloSymbol.SetType( "integer" );

  symbolTable.GetSymbol( "plz" ).SetOffset( 32 );
  symbolTable.GetSymbol( "plz" ).SetType( "bool" );

  // Prints and tests if modifications were made to symbolTable.
  printSymbol( helloSymbol );

  printSymbol( symbolTable.GetSymbol( "hello" ) );
  printSymbol( symbolTable.GetSymbol( "world" ) );
  printSymbol( symbolTable.GetSymbol( "test" ) );
  printSymbol( symbolTable.GetSymbol( "me" ) );
  printSymbol( symbolTable.GetSymbol( "plz" ) );

  symbolTable.EnterBlock();
  {
    printSymbol( symbolTable.GetSymbol( "test" ) );
    printSymbol( symbolTable.GetSymbol( "me" ) );
    printSymbol( symbolTable.GetSymbol( "plz" ) );
  }
  symbolTable.ExitBlock();
}

void printSymbol( const Symbol& symbol )
{
  std::cout << "Symbol: " << symbol.GetName() << " Level: " << symbol.GetLevel() << std::endl;
  std::cout << "  Offset: " << symbol.GetOffset() << std::endl;
  std::cout << "  Type: " << symbol.GetType() << std::endl;
}
